package com.qyer.commons.concurrent.assemblingline;

import com.qyer.commons.concurrent.ArrayListBulk;
import com.qyer.commons.concurrent.GenericLinkedBlockingQueue;

import java.util.List;

/**
 * User: Z J Wu Date: 2016/06/07 Time: 00:04 Package: com.qyer.commons.concurrent
 */
public class Differential<T> {

  private int nextBulkSize;

  private ArrayListBulk<T> storage;

  private GenericLinkedBlockingQueue<ArrayListBulk<T>> conveyor;

  public Differential(int nextBulkSize, GenericLinkedBlockingQueue<ArrayListBulk<T>> conveyor) {
    this.nextBulkSize = nextBulkSize;
    this.storage = ArrayListBulk.newArrayListBulkByCapacity(nextBulkSize);
    this.conveyor = conveyor;
  }

  public void addCheckPush(final ArrayListBulk<T> input) throws InterruptedException,
    AssemblingLineException {
    while (!input.isEmpty()) {
      checkAndPush();
      List<T> sub = input.cut(storage.remain());
      storage.addAll(sub);
    }
  }

  public void checkAndPush() throws InterruptedException {
    if (storage.isFull()) {
      conveyor.put(storage);
      storage = ArrayListBulk.newArrayListBulkByCapacity(nextBulkSize);
    }
  }

  public void flush() throws InterruptedException {
    conveyor.put(storage);
  }

  public static void main(String[] args) throws AssemblingLineException, InterruptedException {
    int nextBulkSize = 5;
    Differential<Integer> differential = new Differential<>(nextBulkSize, null);
    ArrayListBulk<Integer> bulk;

    for (int i = 1; i <= 13; i++) {
      System.out.println("---------------------------------");
      bulk = ArrayListBulk.newArrayListBulkByCapacity(i);
      for (int j = 1; j <= i; j++) {
        bulk.add(j);
      }
      differential.addCheckPush(bulk);
    }
    differential.flush();
  }
}
